﻿// -----------------------------------------------------------------------
// <copyright file="PostProcessing.cs" company="Image Processing Course Project">
// Created 31/10/2011
// </copyright>
// -----------------------------------------------------------------------

namespace ImageProcessing.IntermediateClasses
{
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using ImageProcessing.IntermediateClasses;
    using ImageProcessing.Utilities;

    /// <summary>
    /// Class for PostProcessing Operations
    /// </summary>
    public class PostProcessing
    {
        /// <summary>
        /// Normalization post processing method
        /// </summary>
        /// <param name="oldImage">Original Image</param>
        /// <returns>Normalized buffer</returns>
        public Colour.ColorsStruct[,] Normalization(Bitmap oldImage)
        {
            Colour.ColorsStruct[,] newBuffer = new Colour.ColorsStruct[oldImage.Width, oldImage.Height];
            Colour.ColorsStruct[,] buffer = new Colour.ColorsStruct[oldImage.Width, oldImage.Height];

            int minimumRed = 255, minimumGreen = 255, minimumBlue = 255;
            int maximumRed = 0, maximumGreen = 0, maximumBlue = 0;

            try
            {
                for (int i = 0; i < oldImage.Height; i++)
                {
                    for (int j = 0; j < oldImage.Width; j++)
                    {
                        buffer[j, i].Red = oldImage.GetPixel(j, i).R;
                        buffer[j, i].Green = oldImage.GetPixel(j, i).G;
                        buffer[j, i].Blue = oldImage.GetPixel(j, i).B;
                        if (buffer[j, i].Red > maximumRed)
                        {
                            maximumRed = buffer[j, i].Red;
                        }
                        else if (buffer[j, i].Red < minimumRed)
                        {
                            minimumRed = buffer[j, i].Red;
                        }

                        if (buffer[j, i].Green > maximumGreen)
                        {
                            maximumGreen = buffer[j, i].Green;
                        }
                        else if (buffer[j, i].Green < minimumGreen)
                        {
                            minimumGreen = buffer[j, i].Green;
                        }

                        if (buffer[j, i].Blue > maximumBlue)
                        {
                            maximumBlue = buffer[j, i].Blue;
                        }
                        else if (buffer[j, i].Blue < minimumBlue)
                        {
                            minimumBlue = buffer[j, i].Blue;
                        }
                    }
                }

                ////if (minimumRed >= 0 && maximumRed <= 255 && minimumGreen >= 0 && maximumGreen <= 255
                ////    && minimumBlue >= 0 && maximumBlue <= 255)
                ////{
                ////    return buffer;
                ////}

                for (int i = 0; i < oldImage.Height; i++)
                {
                    for (int j = 0; j < oldImage.Width; j++)
                    {
                        newBuffer[j, i].Red = (int)(((double)(buffer[j, i].Red - minimumRed) / (double)(maximumRed - minimumRed)) * 255);
                        newBuffer[j, i].Green = (int)(((double)(buffer[j, i].Green - minimumGreen) / (double)(maximumGreen - minimumGreen)) * 255);
                        newBuffer[j, i].Blue = (int)(((double)(buffer[j, i].Blue - minimumBlue) / (double)(maximumBlue - minimumBlue)) * 255);
                    }
                }

                return newBuffer;
            }
            catch (Exception ex)
            {
                Logger.LogException(ex);
                throw;
            }
        }

        /// <summary>
        /// Normalization post processing method
        /// </summary>
        /// <param name="oldImage">Original Image</param>
        /// <param name="width">Image width</param>
        /// <param name="height">Image Height</param>
        /// <returns>ColorsStruct buffer</returns>
        public Colour.ColorsStruct[,] Normalization(Colour.ColorsStruct[,] oldImage, int width, int height)
        {
            Colour.ColorsStruct[,] newBuffer = new Colour.ColorsStruct[width, height];
            Colour.ColorsStruct[,] buffer = new Colour.ColorsStruct[width, height];

            int minimumRed = 255, minimumGreen = 255, minimumBlue = 255;
            int maximumRed = 0, maximumGreen = 0, maximumBlue = 0;

            try
            {
                for (int i = 0; i < height; i++)
                {
                    for (int j = 0; j < width; j++)
                    {
                        buffer[j, i].Red = oldImage[j, i].Red;
                        buffer[j, i].Green = oldImage[j, i].Green;
                        buffer[j, i].Blue = oldImage[j, i].Blue;
                        if (buffer[j, i].Red > maximumRed)
                        {
                            maximumRed = buffer[j, i].Red;
                        }
                        else if (buffer[j, i].Red < minimumRed)
                        {
                            minimumRed = buffer[j, i].Red;
                        }

                        if (buffer[j, i].Green > maximumGreen)
                        {
                            maximumGreen = buffer[j, i].Green;
                        }
                        else if (buffer[j, i].Green < minimumGreen)
                        {
                            minimumGreen = buffer[j, i].Green;
                        }

                        if (buffer[j, i].Blue > maximumBlue)
                        {
                            maximumBlue = buffer[j, i].Blue;
                        }
                        else if (buffer[j, i].Blue < minimumBlue)
                        {
                            minimumBlue = buffer[j, i].Blue;
                        }
                    }
                }

                ////if (minimumRed >= 0 && maximumRed <= 255 && minimumGreen >= 0 && maximumGreen <= 255
                ////    && minimumBlue >= 0 && maximumBlue <= 255)
                ////{
                ////    return buffer;
                ////}

                for (int i = 0; i < height; i++)
                {
                    for (int j = 0; j < width; j++)
                    {
                        newBuffer[j, i].Red = (int)(((double)(buffer[j, i].Red - minimumRed) / (double)(maximumRed - minimumRed + 0.001)) * 255);
                        newBuffer[j, i].Green = (int)(((double)(buffer[j, i].Green - minimumGreen) / (double)(maximumGreen - minimumGreen + 0.001)) * 255);
                        newBuffer[j, i].Blue = (int)(((double)(buffer[j, i].Blue - minimumBlue) / (double)(maximumBlue - minimumBlue + 0.001)) * 255);
                    }
                }

                return newBuffer;
            }
            catch (Exception ex)
            {
                Logger.LogException(ex);
                throw;
            }
        }

        /// <summary>
        /// Cut off Post Processing method
        /// </summary>
        /// <param name="color">Color value</param>
        /// <returns>New Color value</returns>
        public double CutOff(double color)
        {
            try
            {
                if (color > 255)
                {
                    color = 255;
                }
                else
                    if (color < 0)
                    {
                        color = 0;
                    }

                return color;
            }
            catch (Exception ex)
            {
                Logger.LogException(ex);
                throw;
            }
        }
    }
}
